#ifndef CLIENT_CONNECTS_HANDLER
#define CLIENT_CONNECTS_HANDLER

#include "ClientSocketHandler.cpp"
#include "ClientRequestAnalyzer.cpp"
#include "Tools.cpp"
#include "UrlConverter.cpp"
#include "FileHandler.cpp"
#include "FileScanner.cpp"
#include "PathNodeManager.cpp"
#include "HtmlLabels.cpp"

class ClientConnectsHandler
{
    private:
    struct ThreadData
    {
        public:
        int ClientSocket;
        sockaddr_in ClientAddr;
        ThreadData(int socket, sockaddr_in addr)
        {
            ClientSocket = socket;
            ClientAddr = addr;
        }
    };
public:
    bool AddClientConnect(int clientSocket, sockaddr_in clientAddr)
    {
        pthread_t id;
        ThreadData *threadData = new ThreadData(clientSocket, clientAddr);
        int ret = pthread_create(&id, NULL, Run, (void *)threadData);
        if(ret != 0)
        {
            PrintLine("线程创建失败 [%d]", ret);
            return false;
        }
        return true;
    }

    static void *Run(void *data)
    {
        ThreadData *threadData = (ThreadData*)data;
        ClientSocketHandler clientSocketHandler(threadData->ClientSocket);
        while (1)
        {
            ClientRequestAnalyzer clientRequestAnalyzer(&clientSocketHandler);
            if (clientRequestAnalyzer.AnalyzeSuccessed() == false)
            {
                PrintLine("退出客户端请求处理方法");
                break;
            }
            PrintLine("request name: [%s]", clientRequestAnalyzer.GetRequestName().c_str());
            PrintLine("url: [%s]", clientRequestAnalyzer.GetUrl().c_str());
            PrintLine("http version: [%s]", clientRequestAnalyzer.GetHttpVersion().c_str());
            PrintLine("Cache-Control: [%s]", clientRequestAnalyzer.GetKeyDataByKey("Cache-Control").c_str());

            std::string localStr = UrlConverter::ConvertFromUrl(clientRequestAnalyzer.GetUrl());
            PrintLine("local str [%s]", localStr.c_str());
            PrintLine("convert to url [%s]", UrlConverter::ConvertToUrl(localStr).c_str());
            std::string fullPath = RootPath + localStr;
            if(FileHandler::IsFileExist(fullPath) == false)
            {
                continue;
            }
            if(FileHandler::IsOrdinaryFile(fullPath))
            {
                FileHandler fileHandler(fullPath);
                ResponseHeader responseHeader;
                PathNodeManager pathNodeManager(localStr);
                responseHeader.SetContentLength(fileHandler.GetFileSize());
                std::string contentType = Tools::GetContentTypeByExtendName(Tools::GetExtendName(pathNodeManager.GetNameByIndex(pathNodeManager.GetLength()-1)));
                responseHeader.SetContentType(contentType);
                std::string header = responseHeader.GetString();
                clientSocketHandler.WriteSocket(header.c_str(), header.length());

                Tools::SendFile(fullPath, &clientSocketHandler);
            }
            else if(FileHandler::IsDirectoryFile(fullPath))
            {
                FileScanner fileScanner(fullPath);
                PathNodeManager pathNodeManager(localStr);
                Label_PairDefault htmlLabel("html");
                htmlLabel.AddAttr("lang", "zh-CN");

                Label_PairDefault aLabel_0("a");
                aLabel_0.SetContent("WebRoot");
                aLabel_0.AddAttr("href", "/");

                Label_PairDefault labelLabel("label");
                labelLabel.SetContent("/");

                Label_SingleDefault metaLabel("meta");
                metaLabel.AddAttr("charset", "utf-8");

                Label_PairDefault headLabel("head");
                headLabel.SetContent("<meta charset=\"utf-8\">");

                std::string htmlContent = headLabel.GetString();
                htmlContent += aLabel_0.GetString();
                htmlContent += labelLabel.GetString();
                for(int i = 0;i<pathNodeManager.GetLength();i++)
                {
                    Label_PairDefault aLabel("a");
                    aLabel.SetContent(pathNodeManager.GetNameByIndex(i));
                    aLabel.AddAttr("href", pathNodeManager.GetPath_UrlMode(i));

                    htmlContent += aLabel.GetString();
                    htmlContent += labelLabel.GetString();
                }
                htmlContent += "</br></br></br></br></br>";
                Label_PairDefault tableLabel("table");
                tableLabel.AddAttr("border", "1");
                tableLabel.AddAttr("cellspacing", "0");
                tableLabel.AddAttr("cellpadding", "8");
                Label_PairDefault tbodyLabel("tbody");
                std::string tabelContent = "";
                for(int i = 0;i<fileScanner.GetLength();i++)
                {

                    Label_PairDefault trLabel("tr");
                    Label_PairDefault tdLabel_0("td"), tdLabel_1("td");
                    Label_PairDefault aLabel_0("a"), aLabel_1("a");
                    std::string fileName = fileScanner.GetFileNameByIndex(i);
                    std::string fileUrl = pathNodeManager.GetPath_UrlMode(pathNodeManager.GetLength() - 1) + UrlConverter::ConvertToUrl(fileScanner.GetFileNameByIndex(i));
                    aLabel_0.SetContent(fileName);
                    aLabel_0.AddAttr("href", fileUrl);
                    tdLabel_0.SetContent(aLabel_0.GetString());

                    if(fileScanner.GetFileTypeByIndex(i) == DT_DIR)
                    {
                        trLabel.AddAttr("bgcolor", "#EEEECC");
                    }
                    else if(fileScanner.GetFileTypeByIndex(i) == DT_REG)
                    {
                        aLabel_1.SetContent("下载");
                        aLabel_1.AddAttr("href", fileUrl);
                        aLabel_1.AddAttr("download", fileName);
                        tdLabel_1.SetContent(aLabel_1.GetString());
                    }
                    trLabel.SetContent(tdLabel_0.GetString() + tdLabel_1.GetString());
                    tabelContent += trLabel.GetString();
                }
                tbodyLabel.SetContent(tabelContent);
                tableLabel.SetContent(tbodyLabel.GetString());
                htmlContent += tableLabel.GetString();
                htmlLabel.SetContent(htmlContent);
                PrintLine(htmlLabel.GetString().c_str());
                std::string htmlCode = htmlLabel.GetString();

                ResponseHeader responseHeader;
                responseHeader.SetContentLength(htmlCode.length());
                responseHeader.SetContentType(Tools::GetContentTypeByExtendName("html"));
                std::string header = responseHeader.GetString();
                clientSocketHandler.WriteSocket(header.c_str(), header.length());

                // Tools::SendFile(fullPath, &clientSocketHandler);
                clientSocketHandler.WriteSocket(htmlCode.c_str(), htmlCode.length());
            }



            std::string test = "123";
            char testCs[] = "123";
            PrintLine("test length %d", test.length());
            PrintLine("testCs length %d", sizeof(testCs));
        }
        delete(threadData);
        return NULL;
    }
};

#endif